{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ea6c0c1b",
   "metadata": {},
   "source": [
    "# FACTS devices"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f767d41",
   "metadata": {},
   "source": [
    "# We implement the FACTS devices based on the following source:\n",
    "\n",
    "    A. Panosyan, \"Modeling of advanced power transmission system controllers\",\n",
    "    Ph.D. dissertation, Gottfried Wilhelm Leibniz Universität Hannover, 2010.\n",
    "\n",
    "We reproduce the case study from the source using the following grid model:\n",
    "\n",
    "![title](facts/facts_case_study_grid.png)\n",
    "\n",
    "So far, we have implemented the following FACTS devices:\n",
    "- Static Var Compensator (SVC)\n",
    "- Static Synchronous Compensator (SSC) \n",
    "- Thyristor-Controlled Series Capacitor (TCSC)\n",
    "- Voltage Source Converter Based High Voltage Direct Current (VSC-HVDC)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cfa025b",
   "metadata": {},
   "source": [
    "## Reference: case study grid\n",
    "\n",
    "First, we import the required functions and set up plotting, the grid model and the data for the timeseries simulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd9fdecb",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:47.429537Z",
     "start_time": "2025-10-20T06:06:43.392544Z"
    }
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from pandapower.test.loadflow.test_facts import facts_case_study_grid\n",
    "from pandapower.timeseries import DFData, OutputWriter\n",
    "from pandapower.timeseries.run_time_series import run_timeseries\n",
    "from pandapower.control import ConstControl\n",
    "from pandapower.pf.create_jacobian_facts import calc_y_svc_pu\n",
    "from pandapower.run import runpp\n",
    "from pandapower.create import (\n",
    "    create_bus,\n",
    "    create_buses,\n",
    "    create_bus_dc,\n",
    "    create_ssc,\n",
    "    create_svc,\n",
    "    create_vsc,\n",
    "    create_tcsc,\n",
    "    create_line_dc,\n",
    "    create_line_from_parameters,\n",
    "    create_line_dc_from_parameters,\n",
    "    create_empty_network,\n",
    "    create_load,\n",
    "    create_ext_grid,\n",
    ")\n",
    "from pandapower.toolbox.grid_modification import drop_lines\n",
    "from pandapower.plotting.simple_plot import simple_plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13836783",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:47.444997Z",
     "start_time": "2025-10-20T06:06:47.435990Z"
    }
   },
   "outputs": [],
   "source": [
    "VOLTAGE_KV = \"Voltage (kV)\"\n",
    "RES_BUS_VM_PU = \"res_bus.vm_pu\"\n",
    "LEGEND_KWARGS = {\"loc\": \"upper center\", \"bbox_to_anchor\": (0.5, -0.15), \"title\": \"Bus\", \"ncol\": 3}\n",
    "THYRISTOR_ANGLE = \"Thyristor firing angle (degree)\"\n",
    "\n",
    "def plot_result(ax, result, title, ylabel, ylim=None, yticks=None, legend=False, legend_kwargs=None):\n",
    "    result.plot(ax=ax, legend=False)\n",
    "    if legend:\n",
    "        kwargs = {} if legend_kwargs is None else legend_kwargs\n",
    "        ax.legend(**kwargs)\n",
    "    ax.set_title(title)\n",
    "    ax.set_ylabel(ylabel)\n",
    "    ax.set_xlabel(\"Time (h)\")\n",
    "    ax.set_xscale('linear')\n",
    "    locs = np.array([-24,   0,  24,  48,  72,  95])\n",
    "    labels = ['00:00','00:00','06:00','12:00','18:00',\"23:45\"]\n",
    "    ax.set_xticks(locs, labels)\n",
    "    ax.set_xlim([0, 95])\n",
    "    if ylim is not None:\n",
    "        ax.set_ylim(ylim)\n",
    "    if yticks is not None:\n",
    "        ax.set_yticks(yticks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a9eeea6f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:47.612957Z",
     "start_time": "2025-10-20T06:06:47.451999Z"
    }
   },
   "outputs": [],
   "source": [
    "net = facts_case_study_grid()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5d105ac",
   "metadata": {},
   "source": [
    "All loads are considered constant. The output of the wind park is configured via a wind power profile. \n",
    "The plot below shows the wind power profile used in the timeseries simulation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25c2a3a6",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:47.833486Z",
     "start_time": "2025-10-20T06:06:47.617959Z"
    }
   },
   "outputs": [],
   "source": [
    "#### define and prepare the generation and load profiles.\n",
    "\n",
    "wind_profile = pd.read_csv(r\"facts/facts_case_study_wind_profile.csv\", index_col=0)\n",
    "\n",
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "plot_result(ax, wind_profile, \"Wind power generation\", \"Power output (MW)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b28ab53",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:47.864893Z",
     "start_time": "2025-10-20T06:06:47.844890Z"
    }
   },
   "outputs": [],
   "source": [
    "time_steps = wind_profile.index.values\n",
    "wind_ds = DFData(wind_profile)\n",
    "ConstControl(net, element='gen', variable='p_mw', element_index=net.gen.index,\n",
    "             data_source=wind_ds, profile_name=[\"wind_power_mw\"])\n",
    "\n",
    "ow = OutputWriter(net, time_steps, output_path=None)\n",
    "ow.log_variable(\"res_bus\", \"vm_pu\")\n",
    "ow.log_variable(\"res_trafo\", \"q_hv_mvar\")\n",
    "ow.log_variable(\"res_trafo\", \"q_lv_mvar\")\n",
    "ow.log_variable(\"res_gen\", \"p_mw\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04a518c1",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:52.154348Z",
     "start_time": "2025-10-20T06:06:47.871893Z"
    }
   },
   "outputs": [],
   "source": [
    "run_timeseries(net, time_steps, continue_on_divergence=False, recycle=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ac11c722",
   "metadata": {},
   "source": [
    "We do not include the buses \"B1\" and \"B2\" in the result plots because their voltage magnitude is always 1 p.u.\n",
    "The results of the timeseries simulation for the bus voltages is are shown in the plot below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "690953ce",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:52.450470Z",
     "start_time": "2025-10-20T06:06:52.223966Z"
    }
   },
   "outputs": [],
   "source": [
    "vm_pu = ow.output[RES_BUS_VM_PU].copy()\n",
    "vm_pu.columns = net.bus.name.values\n",
    "\n",
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "plot_result(ax, 230 * vm_pu.iloc[:, 2:], \"Bus voltage results\", VOLTAGE_KV, legend=True, legend_kwargs=LEGEND_KWARGS)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87ad4f10",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:52.488894Z",
     "start_time": "2025-10-20T06:06:52.477044Z"
    }
   },
   "outputs": [],
   "source": [
    "vm_pu.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38e1db54",
   "metadata": {},
   "source": [
    "## SVC use case\n",
    "\n",
    "The element SVC is a shunt-connected thyristor-based power electronic device. It regulates the voltage magnitude at the\n",
    "connected bus by adjusting the shunt impedance value. The shunt impedance only has the reactance component\n",
    "(no resistive part). The impedance can be capacitive or inductive, because the device consists of a fixed capacitor in\n",
    "a parallel circuit to the reactor that is regulated by a pair of antiparallel thyristors.\n",
    "The thyristor firing angle regulates the total impedance of the element. The device operates in the value range of the thyristor firing angle between 90° and 180°.\n",
    "\n",
    "The active range of the device is presented in the figure below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fbe25de",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:52.701893Z",
     "start_time": "2025-10-20T06:06:52.505627Z"
    }
   },
   "outputs": [],
   "source": [
    "baseV = 230\n",
    "baseMVA = 1\n",
    "baseZ = baseV ** 2 / baseMVA\n",
    "\n",
    "x = np.arange(90,180.1, 0.1)\n",
    "y = calc_y_svc_pu(np.deg2rad(x), 1 / baseZ, -10 / baseZ)\n",
    "\n",
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "ax.plot(x, 1 / y * baseZ)\n",
    "ax.set_ylim(-100, 100)\n",
    "ax.set_xlabel(THYRISTOR_ANGLE)\n",
    "ax.set_ylabel(\"SVC impedance (Ohm)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2721cf3f",
   "metadata": {},
   "source": [
    "It can be seen that the device has a resonance region\n",
    "between the inductive (positive) and the capacitive (negative) impedance characteristics.\n",
    "In real application, the operation of the device in the resonance region is prohibited.\n",
    "\n",
    "Next, we create the SVC device connected to bus \"B7\" and configure it to regulate the voltage to the set point of 1 p.u."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85408bb9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:52.733052Z",
     "start_time": "2025-10-20T06:06:52.710712Z"
    }
   },
   "outputs": [],
   "source": [
    "create_svc(net, bus=6, x_l_ohm=1, x_cvar_ohm=-10, set_vm_pu=1., thyristor_firing_angle_degree=90, controllable=True)\n",
    "net.svc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b03fc1e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:54.525758Z",
     "start_time": "2025-10-20T06:06:53.190595Z"
    }
   },
   "outputs": [],
   "source": [
    "runpp(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff1b4ae",
   "metadata": {},
   "source": [
    "The results of the power flow calculation for the SVC element are shown below: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "567989e3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:56.147346Z",
     "start_time": "2025-10-20T06:06:56.127807Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_svc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfbcfbe4",
   "metadata": {},
   "source": [
    "As you may noticed, the `thyrister_firing_angle_degree` in `net.res_svc` differs from the `net.svc` table. This is because `controllable` is True so that the value can be considered as starting value for the Newton Raphson algorithm. If we switch `controllable` to False and considere `thyrister_firing_angle_degree` next to the previous result, the new result will be next to the previous result but without adjusted `thyrister_firing_angle_degree` for voltage control."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c100afc",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:06:56.627882Z",
     "start_time": "2025-10-20T06:06:56.559117Z"
    }
   },
   "outputs": [],
   "source": [
    "net.svc.at[0, \"controllable\"] = False\n",
    "net.svc.at[0, \"thyristor_firing_angle_degree\"] = 143.625\n",
    "runpp(net)\n",
    "print(net.res_svc)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d38da091",
   "metadata": {},
   "source": [
    "Next, we execute the timeseries simulation and plot the results (again with controlled voltage)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "647348c5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:07.933115Z",
     "start_time": "2025-10-20T06:06:56.784875Z"
    }
   },
   "outputs": [],
   "source": [
    "net.svc.at[0, \"controllable\"] = True\n",
    "ow.log_variable(\"res_svc\", \"thyristor_firing_angle_degree\")\n",
    "run_timeseries(net, time_steps=time_steps, continue_on_divergence=True, recycle=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eca8751b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:08.334290Z",
     "start_time": "2025-10-20T06:07:07.947494Z"
    }
   },
   "outputs": [],
   "source": [
    "vm_pu_svc = ow.output[RES_BUS_VM_PU].copy()\n",
    "vm_pu_svc.columns = net.bus.name.values\n",
    "\n",
    "_, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))\n",
    "plot_result(ax1, 230 * vm_pu.iloc[:, 2:], \"Bus voltage without SVC\", VOLTAGE_KV,\n",
    "            legend=True, legend_kwargs=LEGEND_KWARGS)\n",
    "plot_result(ax2, 230 * vm_pu_svc.iloc[:, 2:], \"Bus voltage with SVC\", VOLTAGE_KV,\n",
    "            legend=True, legend_kwargs=LEGEND_KWARGS)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c978f73b",
   "metadata": {},
   "source": [
    "The necessary thyristor firing angle to control the voltage is presented in the next plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6016bbd2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:08.666271Z",
     "start_time": "2025-10-20T06:07:08.364010Z"
    }
   },
   "outputs": [],
   "source": [
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "thyristor_firing_angle =  ow.output[\"res_svc.thyristor_firing_angle_degree\"].copy() \n",
    "\n",
    "plot_result(ax, thyristor_firing_angle, \n",
    "            \"Thyristor firing angle of SVC\", THYRISTOR_ANGLE)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dcdf6223",
   "metadata": {},
   "source": [
    "# SSC use case (STATCOM)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "472665b8",
   "metadata": {},
   "source": [
    "The Static Synchronous Compensator (SSC), also known as STATCOM, is a shunt connected Flexible AC Transmission System\n",
    "(FACTS) controller. It connects an AC system to a Voltage Source Converter (VSC) through a coupling transformer.\n",
    "The SSC is used for reactive shunt compensation. Since the VSC is not connected to a power source, there is no active\n",
    "power exchange between the SSC and the AC system. Consequently, the SSC can only control the voltage magnitude of\n",
    "the AC system. At this use case, for the purpose of comparison, the SVC at bus B7 is replaced by a STATCOM to control the voltage amplitude to 230 kV.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2991dcd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:08.780045Z",
     "start_time": "2025-10-20T06:07:08.695212Z"
    }
   },
   "outputs": [],
   "source": [
    "# net = facts_case_study_grid()\n",
    "# putting svc out of serivce and replace it with ssc\n",
    "net.svc.in_service = False\n",
    "\n",
    "create_ssc(net, bus=6, r_ohm=0, x_ohm=5, set_vm_pu=1, controllable=True, in_service=True, vm_internal_pu=1.02, va_internal_degree=0)\n",
    "# r_ohm, x_ohm are the parameters for the coupling transformer\n",
    "\n",
    "runpp(net, init='flat')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fc0f1115",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:08.827182Z",
     "start_time": "2025-10-20T06:07:08.788106Z"
    }
   },
   "outputs": [],
   "source": [
    "net.ssc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9562b1be",
   "metadata": {},
   "source": [
    "The results of the power flow calculation for the SSC element are shown below: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "41d7a3be",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:08.982040Z",
     "start_time": "2025-10-20T06:07:08.972240Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_ssc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c20bed37",
   "metadata": {},
   "source": [
    "we can confirm that the voltage magnitude at the bus 'B7' which has the index 6,is maintained at 1 vm_pu buy checking bus voltages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "175aaebd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:09.600018Z",
     "start_time": "2025-10-20T06:07:09.584109Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_bus"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9cdf87f",
   "metadata": {},
   "source": [
    "Next, we execute the timeseries simulation and plot the results, in comparison to svc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0e2bdbe0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:17.584823Z",
     "start_time": "2025-10-20T06:07:09.857197Z"
    }
   },
   "outputs": [],
   "source": [
    "ow.log_variable(\"res_ssc\", \"vm_internal_pu\")\n",
    "\n",
    "run_timeseries(net, time_steps=time_steps, continue_on_divergence=False, recycle=False,init='flat')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f8df72a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:18.412498Z",
     "start_time": "2025-10-20T06:07:17.719159Z"
    }
   },
   "outputs": [],
   "source": [
    "vm_pu_ssc = ow.output[RES_BUS_VM_PU].copy()\n",
    "vm_pu_ssc.columns = net.bus.name.values\n",
    "\n",
    "_, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(16, 4))\n",
    "plot_result(ax1, 230 * vm_pu.iloc[:, 2:], \"Bus voltage without SVC or SSC\", VOLTAGE_KV,\n",
    "            legend=True, legend_kwargs=LEGEND_KWARGS)\n",
    "plot_result(ax2, 230 * vm_pu_svc.iloc[:, 2:], \"Bus voltage with SVC\", VOLTAGE_KV,\n",
    "            legend=True, legend_kwargs=LEGEND_KWARGS)\n",
    "plot_result(ax3, 230 * vm_pu_ssc.iloc[:, 2:], \"Bus voltage with SSC\", VOLTAGE_KV,\n",
    "            legend=True, legend_kwargs=LEGEND_KWARGS)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b15b07b",
   "metadata": {},
   "source": [
    "Next, we compare the converter output voltage of the ssc device to the svc thyristor firing angle:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd4a321a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:18.849528Z",
     "start_time": "2025-10-20T06:07:18.422170Z"
    }
   },
   "outputs": [],
   "source": [
    "vm_pu_ssc = ow.output[\"res_ssc.vm_internal_pu\"].copy()\n",
    "vm_pu_ssc\n",
    "_, (ax1,ax2) = plt.subplots(nrows=1, ncols=2, figsize=(16, 5))\n",
    "\n",
    "plot_result(ax1, thyristor_firing_angle, \n",
    "            \"Thyristor firing angle of SVC\", THYRISTOR_ANGLE)\n",
    "\n",
    "plot_result(ax2, vm_pu_ssc*230, \n",
    "            \"Converter output voltage VSC\", \"Internal SSC Voltage (kV)\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3754bec5",
   "metadata": {},
   "source": [
    "## TCSC use case\n",
    "\n",
    "In this use case, we connect a TCSC controllable element in series at the start of line \"L4\", then we execute a time series simulation when the TCSC element is active and when it is not active. To this end, we create an auxiliary bus and connect the TCSC element to it and reconnect the line \"L4\".\n",
    "\n",
    "The approach is to adjust the structure of the grid before running the simulation.\n",
    "\n",
    "Initial set-up:\n",
    "\n",
    "    B4--------(Line 4)-------B6 \n",
    "\n",
    "New set-up:\n",
    "\n",
    "    B4--(TCSC)----aux------(Line 4)-------B6\n",
    "\n",
    "We need to apply the following steps:\n",
    "\n",
    "- Step 1: define the necessary parameters: $X_L$, $X_{C_{var}}$, thyristor firing angle and the active power set point.\n",
    "- Step 2: add an auxiliary bus to connect the TCSC and reconnect the line.\n",
    "- Step 3: identify the line 4 and reconnect it - adjust the data so that the line 4 is connected to the bus B4 as from_bus and aux as to_bus.\n",
    "- Step 4: create the TCSC betwen B4 and the auxiliary bus, provide the required parameters and set controllable to True. This will activate the TCSC element.\n",
    "\n",
    "Note: if controllable is set to False, TCSC will act as a fixed impedance corresponding to the parameters $X_L$ and  $X_{C_{var}}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b99974be",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:18.953422Z",
     "start_time": "2025-10-20T06:07:18.862983Z"
    }
   },
   "outputs": [],
   "source": [
    "xl = 7.6\n",
    "xc = -47\n",
    "\n",
    "f = net.bus.loc[net.bus.name == \"B4\"].index.values[0]\n",
    "t = net.bus.loc[net.bus.name == \"B6\"].index.values[0]\n",
    "aux = create_bus(net, 230, \"aux\")\n",
    "l = net.line.loc[(net.line.from_bus == f) & (net.line.to_bus == t)].index.values[0]\n",
    "net.line.loc[l, \"from_bus\"] = aux\n",
    "\n",
    "create_tcsc(net, from_bus=f, to_bus=aux, x_l_ohm=xl, x_cvar_ohm=xc, set_p_to_mw=-100,\n",
    "               thyristor_firing_angle_degree=140, controllable=True)\n",
    "net.svc.in_service = False\n",
    "net.ssc.in_service = False\n",
    "\n",
    "net.tcsc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff6eb6e9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:19.326816Z",
     "start_time": "2025-10-20T06:07:19.211187Z"
    }
   },
   "outputs": [],
   "source": [
    "runpp(net, init=\"dc\")\n",
    "net.res_tcsc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "553d6cfa",
   "metadata": {},
   "source": [
    "Now, after loading the grid and creating TCSC element, we again set up the timeseries simulation. In the fololowing, we execute the first part of the calculation with the TCSC element with controllable set to True:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2944773c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:23.889446Z",
     "start_time": "2025-10-20T06:07:19.622376Z"
    }
   },
   "outputs": [],
   "source": [
    "ow.log_variable(\"res_tcsc\", \"thyristor_firing_angle_degree\")\n",
    "ow.log_variable(\"res_tcsc\", \"p_from_mw\")\n",
    "ow.log_variable(\"res_tcsc\", \"q_from_mvar\")\n",
    "ow.log_variable(\"res_tcsc\", \"ql_mvar\")\n",
    "\n",
    "run_timeseries(net, time_steps[:48], continue_on_divergence=True, recycle=False, max_iteration=100, init=\"results\")\n",
    "p_controllable = ow.output[\"res_tcsc.p_from_mw\"].copy()\n",
    "angle_controllable = ow.output[\"res_tcsc.thyristor_firing_angle_degree\"].copy()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45b730f7",
   "metadata": {},
   "source": [
    "Now we set the TCSC parameter controllable to False and configure the thyristor firing angle to a fixed value of 90 degrees, then again execute the simulation. In the fololowing, we execute the second part of the calculation with the TCSC element acting as a fixed impedance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e8dc4f08",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:26.020547Z",
     "start_time": "2025-10-20T06:07:23.909001Z"
    }
   },
   "outputs": [],
   "source": [
    "net.tcsc.controllable = False\n",
    "net.tcsc.thyristor_firing_angle_degree = 90\n",
    "run_timeseries(net, time_steps[48:], continue_on_divergence=True, recycle=False, max_iteration=100, init=\"results\")\n",
    "p_not_controllable = ow.output[\"res_tcsc.p_from_mw\"].copy()\n",
    "angle_not_controllable = ow.output[\"res_tcsc.thyristor_firing_angle_degree\"].copy()\n",
    "p_total = pd.concat([p_controllable, p_not_controllable])\n",
    "angle_total = pd.concat([angle_controllable, angle_not_controllable])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "643e1baa",
   "metadata": {},
   "source": [
    "Now we plot the active power transfer from buses 4 to 6 through the TCSC element and the line \"L4\" when TCSC is controllable (first half) and not controllable (second half):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d9174eaa",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:26.284932Z",
     "start_time": "2025-10-20T06:07:26.029480Z"
    }
   },
   "outputs": [],
   "source": [
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "plot_result(ax, p_total, \"Active power flow through TCSC\", \"P (MW)\", [-20, 180])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90b9685d",
   "metadata": {},
   "source": [
    "The corresponding thyristor firing angle is shown in the plot below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a11822b9",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:26.648250Z",
     "start_time": "2025-10-20T06:07:26.305643Z"
    }
   },
   "outputs": [],
   "source": [
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "plot_result(ax, angle_total, \"Thyristor firing angle of TCSC\", THYRISTOR_ANGLE)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "636dcddb",
   "metadata": {},
   "source": [
    "# VSC-HVDC use case"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85febedc",
   "metadata": {},
   "source": [
    "The model of VSC-HVDC use case is now validated by replaceing one of the two cables connecting the wind farm to the\n",
    "transmission system.A VSC-HVDC with 30km dc cable is employed between B3 and B4 instead of L2. nevertheless, connecting a DC cable between B3 and B4 cannot be done without converters (VSCs).Thus, it is required to create the DC system first then connect it with the AC system. in our case the DC system is consist of the 30km dc cable and two dc buses to be connected at the DC side of the VSCs. so the structure should look like the follwing"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5e08e85e",
   "metadata": {},
   "source": [
    "Initial set-up:\n",
    "\n",
    "    B3--------(Line 2)-------B4 \n",
    "    \n",
    "The new set-up:\n",
    "    \n",
    "    B3-----VSC1---Bdc---------(30km dc line)--------Bdc----VSC2----B4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84f1bff3",
   "metadata": {},
   "source": [
    "Now, lets import the grid in its intial set-up and apply the necessary adjustments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b641c55",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:27.144548Z",
     "start_time": "2025-10-20T06:07:26.662714Z"
    }
   },
   "outputs": [],
   "source": [
    "net = facts_case_study_grid()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38e139cc",
   "metadata": {},
   "source": [
    "First, we put line 2 out of service or we drop it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18ce4661",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:27.237596Z",
     "start_time": "2025-10-20T06:07:27.158511Z"
    }
   },
   "outputs": [],
   "source": [
    "drop_lines(net,lines=[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18bb84e6",
   "metadata": {},
   "source": [
    "Now, we create dc buses and dc line(the 30 dc cable)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65bfe339",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:27.342270Z",
     "start_time": "2025-10-20T06:07:27.256564Z"
    }
   },
   "outputs": [],
   "source": [
    "create_bus_dc(net, 300, 'A')\n",
    "create_bus_dc(net, 300, 'B')\n",
    "\n",
    "create_line_dc(net,0,1,30,std_type='2400-AL')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbed83a5",
   "metadata": {},
   "source": [
    "Next, we create the VSCs, configure them and then connect the DC with the AC system.In our case, a single degree of freedom at each of the VSCs is employed to control the voltage magnitude at the two buses B3 and B4. The second degree of freedom of the rectifier side VSC2 (B3) is applied to control the active power flow either at 300 MW or at wind power level."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bbde9f45",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:27.405355Z",
     "start_time": "2025-10-20T06:07:27.381392Z"
    }
   },
   "outputs": [],
   "source": [
    "create_vsc(net, bus=2, bus_dc=0, r_ohm=0, x_ohm=15, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac =\"vm_pu\", control_value_ac=1,\n",
    "              control_mode_dc=\"p_mw\", control_value_dc=-300)\n",
    "#### TODO: explain the contro_value_dc being in negative \n",
    "create_vsc(net, bus=3, bus_dc=1, r_ohm=0, x_ohm=15, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac =\"vm_pu\", control_value_ac=1,\n",
    "              control_mode_dc=\"vm_pu\", control_value_dc=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9683a068",
   "metadata": {},
   "source": [
    "Now, after loading the grid and creating VSC-HVDC element, we again set up the timeseries simulation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55a201e4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:27.543317Z",
     "start_time": "2025-10-20T06:07:27.448772Z"
    }
   },
   "outputs": [],
   "source": [
    "#### define and prepare the generation and load profiles.\n",
    "\n",
    "wind_profile = pd.read_csv(r\"facts/facts_case_study_wind_profile.csv\", index_col=0)\n",
    "\n",
    "wind_profile['vsc_set_p'] = -np.clip(wind_profile['wind_power_mw'],0,300)\n",
    "wind_profile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db524747652949e7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:38.510871Z",
     "start_time": "2025-10-20T06:07:27.742236Z"
    }
   },
   "outputs": [],
   "source": [
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "plot_result(ax, wind_profile, \"Wind power generation\", \"Power output (MW)\")\n",
    "time_steps = wind_profile.index.values\n",
    "wind_ds = DFData(wind_profile)\n",
    "ConstControl(net, element='gen', variable='p_mw', element_index=net.gen.index,\n",
    "             data_source=wind_ds, profile_name=[\"wind_power_mw\"])\n",
    "ConstControl(net, element='vsc', variable='control_value_dc', element_index=[0],\n",
    "             data_source=wind_ds, profile_name=[\"vsc_set_p\"])\n",
    "\n",
    "\n",
    "ow = OutputWriter(net, time_steps, output_path=None)\n",
    "\n",
    "ow.log_variable(\"res_vsc\", \"p_dc_mw\")\n",
    "ow.log_variable(\"res_vsc\", \"vm_internal_pu\")\n",
    "ow.log_variable(\"res_vsc\", \"va_internal_degree\")\n",
    "ow.log_variable(\"res_line\", \"p_from_mw\")\n",
    "ow.log_variable(\"res_gen\", \"p_mw\")\n",
    "ow.log_variable(\"res_line_dc\",\"p_from_mw\")\n",
    "run_timeseries(net, time_steps=time_steps, continue_on_divergence=True, recycle=False,init='flat')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b7409f4",
   "metadata": {},
   "source": [
    "Now we plot the result for the power flow thorugh ac and dc lines in comparason with generated power"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d87914b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:38.841706Z",
     "start_time": "2025-10-20T06:07:38.614938Z"
    }
   },
   "outputs": [],
   "source": [
    "line_ac_3_4 =  ow.output['res_line.p_from_mw'].copy()\n",
    "line_dc_3_4 = ow.output['res_line_dc.p_from_mw'].copy()\n",
    "\n",
    "\n",
    "_, (ax) = plt.subplots(1, 1, figsize=(10, 5))\n",
    "\n",
    "results = pd.concat([wind_profile['wind_power_mw'],line_dc_3_4,line_ac_3_4[0]] ,axis=1)\n",
    "results.columns = ['Wind generated active power','Active power flow through DC cable','Active power flow through AC line ']\n",
    "plot_result(ax, results, \n",
    "            \"Active power of VSC-HVDC\", \"P/[MW]\", legend=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d5d7526",
   "metadata": {},
   "source": [
    "Now we plot the control variables at VSC-HVDC for both VSCs the rectifier and the inverter, which are the internal voltage magnitudes and Angles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f15f293e",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:39.413877Z",
     "start_time": "2025-10-20T06:07:38.941631Z"
    }
   },
   "outputs": [],
   "source": [
    "vsc_vm_internal_pu = ow.output['res_vsc.vm_internal_pu'].copy()\n",
    "vsc_va_internal_degree = ow.output['res_vsc.va_internal_degree'].copy()\n",
    "\n",
    "vsc_vm_internal_pu.columns = ['$V_r$','$V_i$']\n",
    "vsc_va_internal_degree.columns = ['$\\delta_r$','$\\delta_i$']\n",
    "\n",
    "\n",
    "_, (ax1,ax2) = plt.subplots(nrows=1, ncols=2, figsize=(16, 5))\n",
    "\n",
    "plot_result(ax1, vsc_vm_internal_pu*230, \n",
    "            \"Voltage Magnitude Control Variables of VSC-HVDC\", \"Voltage Angle (kV)\", legend=True)\n",
    "\n",
    "plot_result(ax2, vsc_va_internal_degree, \n",
    "            \"Voltage Anlges Control Variables of VSC-HVDC\", \"Voltage Angle (degree)\", legend=True)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3bb9f135",
   "metadata": {},
   "source": [
    "# Multi Terminal VSC-HVDC"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa9e7bf4",
   "metadata": {},
   "source": [
    "In the previous example we connceted two terminal dc system to an ac system. but in fact multi terminal VSC-HVDC system can be formulated as we see in the following example"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8965ba53",
   "metadata": {},
   "source": [
    "We first create the AC gird part"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4754d480",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:39.808925Z",
     "start_time": "2025-10-20T06:07:39.515708Z"
    }
   },
   "outputs": [],
   "source": [
    "net = create_empty_network()\n",
    "\n",
    "create_buses(net, 5, 110, geodata=((0, 50), (50, 100), (200, 100), (50, 0), (200, 0)))\n",
    "create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 1, 2, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 3, 4, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_ext_grid(net, 0)\n",
    "create_load(net, 2, 10)\n",
    "create_load(net,4,15);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e3fc049",
   "metadata": {},
   "source": [
    "Now we plot the AC system, blue circles represnet AC buses and black lines represnets AC lines, the triangles represent loads."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd7c809c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:39.964792Z",
     "start_time": "2025-10-20T06:07:39.821498Z"
    }
   },
   "outputs": [],
   "source": [
    "simple_plot(net, plot_loads=True, load_size=2);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5afff5b",
   "metadata": {},
   "source": [
    "Then we create the DC grid part"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2386d5be",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:40.059822Z",
     "start_time": "2025-10-20T06:07:39.986941Z"
    }
   },
   "outputs": [],
   "source": [
    "create_bus_dc(net, 320, 'A', geodata=(50, 100))\n",
    "create_bus_dc(net, 320, 'B', geodata=(200, 50))\n",
    "create_bus_dc(net, 320, 'C', geodata=(200, 100))\n",
    "create_bus_dc(net, 320, 'D', geodata=(200, 0))\n",
    "create_bus_dc(net, 320, 'E', geodata=(50, 0))\n",
    "\n",
    "create_line_dc_from_parameters(net, 0, 1, 100, 0.1, 1)\n",
    "create_line_dc_from_parameters(net, 1, 2, 100, 0.1, 1)\n",
    "create_line_dc_from_parameters(net, 1, 3, 100, 0.1, 1)\n",
    "create_line_dc_from_parameters(net, 1, 4, 100, 0.1, 1);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd1589fe",
   "metadata": {},
   "source": [
    "Next we connect the AC grid with DC grid through VSCs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8841c955-1035-47a6-8b5a-de9410f31307",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:40.304201Z",
     "start_time": "2025-10-20T06:07:40.232531Z"
    }
   },
   "outputs": [],
   "source": [
    "create_vsc(net, bus=1, bus_dc=0, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"q_mvar\",\n",
    "              control_value_ac=3, control_mode_dc=\"vm_pu\", control_value_dc=1)\n",
    "create_vsc(net, bus=2, bus_dc=2, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"q_mvar\",\n",
    "              control_value_ac=10, control_mode_dc=\"p_mw\", control_value_dc=5)\n",
    "create_vsc(net, bus=4, bus_dc=3, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"vm_pu\",\n",
    "              control_value_ac=1.05, control_mode_dc=\"p_mw\", control_value_dc=15)\n",
    "create_vsc(net, bus=3, bus_dc=4, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"vm_pu\",\n",
    "              control_value_ac=1.03, control_mode_dc=\"vm_pu\",control_value_dc=1.02);\n",
    "net.vsc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b0cb19a",
   "metadata": {},
   "source": [
    "Now, we plot both grids. The circles in blue color represent AC buses, the circles in purple color represent DC buses. Light blue squares shows VSCs, the light blue lines are the DC lines, and the triangles represent loads. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c052d51f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:40.613849Z",
     "start_time": "2025-10-20T06:07:40.485893Z"
    }
   },
   "outputs": [],
   "source": [
    "simple_plot(net, plot_loads=True, load_size=2);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1499228e",
   "metadata": {},
   "source": [
    "Now, we present the power flow calculations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "56760f8f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:41.704269Z",
     "start_time": "2025-10-20T06:07:40.734462Z"
    }
   },
   "outputs": [],
   "source": [
    "runpp(net)\n",
    "net.res_line_dc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b182887",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:42.041132Z",
     "start_time": "2025-10-20T06:07:42.014720Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_line"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f9cee0d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:42.742236Z",
     "start_time": "2025-10-20T06:07:42.722581Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_vsc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69259c65",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:43.023355Z",
     "start_time": "2025-10-20T06:07:43.003873Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_bus_dc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ae4b675",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:43.645026Z",
     "start_time": "2025-10-20T06:07:43.632695Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_bus"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3aed0778",
   "metadata": {},
   "source": [
    "# B2B VSC-HVDC"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "310c0107",
   "metadata": {},
   "source": [
    "Now we try another configuration for VSC-HVDC as Back-to-Back(B2B). implementing this configuration\n",
    "requires to connect 2 VSCs (at least) to the same DC Bus. One of the examples of B2B VSC-HVDC is Tres Amigas SuperStation, so let's build it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "016ad824",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:45.677611Z",
     "start_time": "2025-10-20T06:07:44.397680Z"
    }
   },
   "outputs": [],
   "source": [
    "net = create_empty_network()\n",
    "# AC part\n",
    "create_buses(net, 5, 110, geodata=((0, 0), (70, -20), (100, 100), (100, -100), (200, 0)))\n",
    "create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 0, 3, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_line_from_parameters(net, 1, 4, 30, 0.0487, 0.13823, 160, 0.664)\n",
    "create_ext_grid(net, 0)\n",
    "create_load(net, 2, 10)\n",
    "\n",
    "# DC system\n",
    "create_bus_dc(net, 110, 'A',geodata=(80, 20))\n",
    "\n",
    "create_vsc(net, bus=4, bus_dc=0, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"vm_pu\",\n",
    "              control_value_ac=1, control_mode_dc=\"vm_pu\", control_value_dc=1.02)\n",
    "create_vsc(net, bus=2, bus_dc=0, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"vm_pu\",\n",
    "              control_value_ac=1, control_mode_dc=\"p_mw\", control_value_dc=2)\n",
    "create_vsc(net, bus=3, bus_dc=0, r_ohm=0.1, x_ohm=5, r_dc_ohm=0.5, pl_dc_mw=0.01, control_mode_ac=\"vm_pu\",\n",
    "              control_value_ac=1, control_mode_dc=\"p_mw\", control_value_dc=4)\n",
    "\n",
    "runpp(net)\n",
    "simple_plot(net, bus_dc_size=3, vsc_size=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cff25c0",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:45.768023Z",
     "start_time": "2025-10-20T06:07:45.743350Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_vsc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ebe6b42",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:46.032568Z",
     "start_time": "2025-10-20T06:07:46.012719Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_bus_dc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "03d57c29",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T06:07:46.545864Z",
     "start_time": "2025-10-20T06:07:46.523662Z"
    }
   },
   "outputs": [],
   "source": [
    "net.res_bus"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  },
  "vscode": {
   "interpreter": {
    "hash": "19d1d53a962d236aa061289c2ac16dc8e6d9648c89fe79f459ae9a3493bc67b4"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
